/*
 *
 * @author : Jeason Laung
 * @date   : 2019/1/22
 *
 */
import SocketTest from 'websocket-heartbeat-js'
class test extends SocketTest {
  constructor(obj) {
    const websocketJson = {
      url: obj.url,
      pingTimeout: obj.pingTimeout ? obj.pingTimeout : 10000,
      pongTimeout: obj.pongTimeout ? obj.pongTimeout : 30000,
      reconnectTimeout: obj.reconnectTimeout ? obj.reconnectTimeout : 10000,
      pingMsg: obj.pingMsg ? obj.pingMsg : 'helloMsg',
      repeatLimit: obj.repeatLimit ? obj.repeatLimit : null
    }
    super(websocketJson)
  }
}
class Socket {
  /* websocket实例 */
  ws = null

  /* '#'为私有属性，外部不可调用 */

  /* 状态 */
  // 连接状态
  #alive = false
  // 把类的参数传入这里，方便调用
  #params = null
  #pongIndex = true
  /* 计时器 */
  // 重连计时器
  #reconnect_timer = null
  // 心跳计时器
  #heart_timer = null
  #pong_heart_timer = null
  #pong_timer = null
  // 信息onmessage缓存方法
  #message_func = null
  // 重连次数计数
  #reconnectTimes = null
  /* 参数 */
  // ping心跳时间 20秒一次
  heartBeat = 10000
  // 心跳信息：默认为‘helloMsg’随便改，看后台
  heartMsg = 'helloMsg'
  // pong心跳时间 20秒一次
  pongHeartBeat = 25000
  // 心跳信息：默认为‘helloMsg’随便改，看后台
  pongHeartMsg = 'helloMsg'
  // 是否自动重连
  reconnect = true
  // 重连间隔时间
  reconnectTime = 10000
  // 重连次数
  reconnectTimes = 40

  constructor(params) {
    this.#params = params
    this.init()
  }

  /* 初始化 */
  init() {
    // 重中之重，不然重连的时候会越来越快
    clearInterval(this.#reconnect_timer)
    clearInterval(this.#heart_timer)
    clearInterval(this.#pong_heart_timer)
    console.log('剩余重连次数:' + this.#reconnectTimes)
    // 取出所有参数
    const params = this.#params
    // 设置连接路径
    const { url, port } = params
    const global_params = [
      'heartBeat',
      'pongHeartBeat',
      'heartMsg',
      'reconnect',
      'reconnectTime',
      'reconnectTimes'
    ]

    // 定义全局变量
    Object.keys(params).forEach((key) => {
      if (global_params.indexOf(key) !== -1) {
        this[key] = params[key]
      }
    })
    const ws_url = port ? url + ':' + port : url

    // this.ws = null
    delete this.ws
    this.ws = new WebSocket(ws_url)

    // window.console.log(this.#message_func)
    this.onmessage(this.#message_func)

    // 默认绑定事件
    this.ws.onopen = () => {
      // 设置状态为开启
      this.#alive = true
      this.#reconnectTimes = this.reconnectTimes
      // 连接后进入心跳状态
      this.onHeartBeat()
      if (this.#pongIndex) {
        clearInterval(this.#pong_heart_timer)
        this.onPongHeartbeat()
      }
    }
    this.ws.onclose = (e) => {
      // console.log(e, new Date())
      // 设置状态为断开
      this.#alive = false
      clearInterval(this.#reconnect_timer)
      clearInterval(this.#heart_timer)
      clearInterval(this.#pong_heart_timer)
      console.log('websocket断开')
      console.log('websocket重连')
      // 自动重连开启  +  不在重连状态下
      /* 断开后立刻重连 */
      setTimeout(() => {
        this.onReconnect()
      }, this.reconnectTime)
    }
  }

  /*
   *
   * 新增‘心跳事件’和‘重连事件’
   *
   */

  /* 心跳事件 */
  onHeartBeat(func) {
    // 在连接状态下
    if (this.#alive === true) {
      /* 心跳计时器 */
      this.#heart_timer = setInterval(() => {
        // 发送心跳信息
        this.send(this.heartMsg)
        func ? func(this) : false
      }, this.heartBeat)
    }
  }
  /* 心跳事件 */
  onPongHeartbeat() {
    // 在连接状态下
    this.#pong_timer = this.pongHeartBeat
    if (this.#alive === true) {
      /* 心跳计时器 */
      this.#pong_heart_timer = setInterval(() => {
        this.#pong_timer = this.#pong_timer - 1000
        if (this.#pong_timer === 0) {
          this.#pong_timer = this.pongHeartBeat
          clearInterval(this.#pong_heart_timer)
          this.ws.close()
        }
      }, 1000)
    }
  }
  /* 重连事件 */
  onReconnect(func) {
    /* 重连间隔计时器 */
    if (this.reconnect === true) {
      console.log('触发重连函数')
      this.#reconnect_timer = setInterval(() => {
        // 限制重连次数
        if (this.#reconnectTimes <= 0) {
          // 关闭定时器
          // this.#isReconnect = false
          clearInterval(this.#reconnect_timer)
          // 跳出函数之间的循环
          return
        } else {
          // 重连一次-1
          this.#reconnectTimes--
        }
        console.log('进行重连')
        // 进入初始状态
        this.init()
        func ? func(this) : false
      }, this.reconnectTime)
    } else {
      console.log('websocket断开')
    }
  }
  /*
   *
   * 对原生方法和事件进行封装
   *
   */

  // 发送消息
  send(text) {
    if (this.#alive === true) {
      text = typeof text === 'string' ? text : JSON.stringify(text)
      this.ws.send(text)
    }
  }

  // 断开连接
  close() {
    this.reconnect = false
    if (this.#alive === true) {
      this.ws.close()
    }
  }

  // 接受消息
  onmessage(func, all = false) {
    this.ws.onmessage = (data) => {
      if (data.data === 'helloMsg') {
        this.#pong_timer = this.pongHeartBeat
      } else {
        this.#message_func = func
        func(all ? JSON.parse(data) : JSON.parse(data.data))
      }
    }
  }
  // // 下面两个都没用
  // // websocket连接成功事件
  // onopen(func) {
  //   this.ws.onopen = event => {
  //     this.#alive = true
  //     func ? func(event) : false
  //   }
  // }
  // // websocket关闭事件
  // onclose(func) {
  //   this.ws.onclose = event => {
  //     // 设置状态为断开
  //     this.#alive = false
  //     // 自动重连开启  +  不在重连状态下
  //     if (this.reconnect === true) {
  //       /* 断开后立刻重连 */
  //       setTimeout(() => {
  //         this.onReconnect()
  //       }, this.reconnectTime)
  //     }
  //     func ? func(event) : false
  //   }
  // }
  // // websocket错误事件
  onerror(func) {
    this.ws.onerror = (event) => {
      func ? func(event) : false
    }
  }
}
// const ws = new Socket({
//   // 网址（端口是我下面的服务器的端口）
//   'url': 'ws://192.168.16.122:8080/webSocket/gwsBoxData/110111003'
//   // 心跳时间（单位:ms）
//   // 'heartBeat':5000,
//   // 发送心跳信息（支持json传入）(这个一般内容不重要，除非后端变态)
//   // 'heartMsg':'hello',
//   // 开起重连
//   // 'reconnect':true,
//   // 重连间隔时间（单位:ms）
//   // 'reconnectTime':5000,
//   // 重连次数
//   // 'reconnectTimes':10
// })
// // 发送信息
// ws.send({ msg: '你好' })

// // 关闭连接
// ws.close()

// // 心跳事件
// ws.onHeartBeat(() => {
//   console.log('heartbeat')
// })

// // 心跳事件
// ws.onReconnect(() => {
//   console.log('reconnect')
// })

// // 接收信息
// ws.onmessage((data) => {
//   console.log(data)
// })

// // 关闭事件
// ws.onclose((event) => {
//   console.log(event)
// })

// // 开启事件
// ws.onopen((event) => {
//   console.log(event)
// })

// // 异常事件
// ws.onopen((event) => {
//   console.log(event)
// })

// // 更甚至可以直接拿出websocket来用（不推荐）
// ws.ws.send('你好')
export default Socket
